package com.yan.design.two.establish.s1.single;

/**
 * 创建型模式：一.单例模式
 *      分为有8种方式：
 *      1. 饿汉式（静态常量）
 *      2. 饿汉式（静态代码块）
 *      3. 懒汉式（线程不安全）
 *      4. 懒汉式（线程安全，同步方法）
 *      5. 懒汉式（线程安全，同步代码块）
 *      6. 双重检测
 *      7. 静态内部类
 *      8. 枚举
 * @author shengren.yan
 * @create 2022-07-14
 */
public class Single2 {

    public static void main(String[] args) {

        // 3. 懒汉式（线程不安全）
        Single s1 = Single.getSingle();
        Single s2 = Single.getSingle();
        System.out.println(s1==s2);
        s1.id=3;
        System.out.println(s2.id);

        // 4. 懒汉式（线程安全，同步方法）
        Single4 s41 = Single4.getSingle();
        Single4 s42 = Single4.getSingle();
        System.out.println(s41==s42);
        s1.id=3;
        System.out.println(s2.id);

        //  5. 懒汉式（线程安全，同步代码块）  - 不推荐

    }

     // 3. 懒汉式（线程不安全）
     static class Single{
        // 构造方法私有 - 防止对象被new出来，需要去掉static
        private Single(){}
        private static Single single ;
        public static Single getSingle(){
            if (single == null) {
                single = new Single();
            }
            return single;
        }
        private Integer id;
        public Integer getIn() {
             return id;
         }
    }

     // 4. 懒汉式（线程安全，同步方法） -- 增加 synchronized
     static class Single4{
         // 构造方法私有
         private Single4(){}
         private static Single4 single;
         public static synchronized Single4 getSingle(){
             if (single == null) {
                 single = new Single4();
             }
             return single;
         }
         private Integer id;
         public Integer getIn() {
             return id;
         }
     }


     //  5. 懒汉式（线程安全，同步代码块）  - 不推荐
     static class Single5{
         // 构造方法私有
         private Single5(){}
         private static Single5 single;
         public static  Single5 getSingle(){
             if (single == null) {
                 synchronized(Single5.class){
                     single = new Single5();
                 }
             }
             return single;
         }
         private Integer id;
         public Integer getIn() {
             return id;
         }
     }

}
